懒人开关 ESP32控制舵机旋转(基于ESP32+SG90舵机+微信小程序)

您所在的位置:网站首页 esp01 继电器 懒人开关 ESP32控制舵机旋转(基于ESP32+SG90舵机+微信小程序)

懒人开关 ESP32控制舵机旋转(基于ESP32+SG90舵机+微信小程序)

2023-04-11 15:22| 来源: 网络整理| 查看: 265

提示:站在巨人肩膀上的小白,大家可以提出自己的看法。如有侵删;

原文参考链接:esp32单片机控制舵机 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/566948087 文章目录

目录

前言

一、准备步骤

二、使用步骤

1.ESP32和SG90舵机的连接

2.读入数据

3.外壳的打印

4.MQTT连接

若是纯小白,可以看一下这个

导入库和站看日志的方法,若找不到可以从官网上进行下载之后进行导入

前言

        随着智能化时代的到来,你是否想解放双手,实现家居智能化,这多酷啊!!懒人开关专属于你的定制。

有点模糊,但是实际功能实现啦!微信小程序端来自B站小林技术员的个人空间_哔哩哔哩_bilibili

大家可以私信一下;

 

一、准备步骤

先准备一个SG90舵机; 再来一个ESP32单片机; 最后就是很多根杜邦线 ; 安卓线来一条进行烧录的时候使用; 二、使用步骤 1.ESP32和SG90舵机的连接:

先来科普一下舵机的小知识:

        (1)舵机分三条线,分别是棕色:GND;红色:VCC (这里我们采用的是5V电压,力气更大一点个人理解哈);橘色线:脉冲输入(也就是信号线);

        (2)开始接线啦:棕色==GND 红色==自带的5V 橘色==GPIO13

 先上一个ESP32的引脚图,详细内容在图中都有标注,自行查看即可(图是从网上找到的,很详细!如有侵删)

        舵机转动角度与占空比的关系: 占 空 比 = ( 角 度 90 + 0.5 ) ∗ 1023 / 20 占空比=(\frac {角度}{90}+0.5)*1023/20占空比=( 90角度 +0.5)∗1023/20:

舵机的购买和详细知识在这里不做过过多的解释了,自行从参考链接中查询。

2.读入数据

整体就是判断1,0开关,接收到后返回OK;本文采用的是MQTT进行通信,当然后期你也可以自行添加蓝牙的通信方式等等;

代码如下:

int freq = 50; // 1/50秒,50Hz的频率,20ms的周期,这个变量用来存储时钟基准。 int channel = 8; // 通道(高速通道(0 ~ 7)由80MHz时钟驱动,低速通道(8 ~ 15)由 1MHz 时钟驱动。) int resolution = 8; // 分辨率设置为8,就是2的8次方,用256的数值来映射角度,看下方的占空比函数。 const int led = 13; /*****将局部变量已改为全局变量(根据实际需求再自行调整)****/ int degree; float deadZone = 0; String push_msg = "OK"; //最好不要使用max、min...之类的词作为变量,容易被编译器识别成方法、类、函数... float maxs = 32;//对应2.5ms(2.5ms/(20ms/256)) /*****************************/ WiFiClient espClient; // 定义WLAN实例 PubSubClient client(espClient); // 定义PubSubClient的实例 /*****将int degree改为 int c,通过赋值修改degree的值******/ /*****由于该函数中return一个int类型数据,所以应将函数的返回值类型void改为int******/ int calculatePWM(int c) //定义函数用于输出PWM的占空比 { //0-180度 degree = c; /*****************************************************/ //20ms周期内,高电平持续时长0.5-2.5ms,对应0-180度舵机角度,参考上面的180度对应图。 deadZone = 6.4;//对应0.5ms(0.5ms/(20ms/256)) if (degree < 0) degree = 0; if (degree > 200) degree = 180; return (int)(((maxs - deadZone) / 180) * degree + deadZone); //返回度数对应的高电平的数值 }

定义两个主题用于发送和接受;

/*****由于该函数中return一个int类型数据,所以应将函数的返回值类型void改为int******/ int leddev(char* topic, byte* payload, unsigned int length) /*************************************************************************/ { String msg=""; for (int i = 0; i < length; i++) { msg+= (char)payload[i]; } Serial.println(msg); if (msg == "1") { degree = 0; ledcWrite(channel, calculatePWM(180)); // 输出PWM,设置 LEDC 通道的占空比。 client.publish(Mqtt_pub_topic,push_msg.c_str()); return (int)(((maxs - deadZone) / 180) * degree + deadZone); //返回度数对应的高电平的数值 } else { Serial.printf("ok"); client.publish(Mqtt_pub_topic,push_msg.c_str()); ledcWrite(channel, calculatePWM(90)); // 输出PWM,设置 LEDC 通道的占空比。 } }

来一个标志位;

标志位:拿着钥匙进来返回OK 

int flag = 0; void loop() { if (!client.connected()) //如果MQTT服务器连接不成功,则反复重试,连接成功后重新订阅。 { reconnect(); } client.loop(); if(flag==0){ client.publish(Mqtt_pub_topic,push_msg.c_str()); flag=1; Serial.println("发送ok!"); }

看一下端口 

3.外壳的打印

外壳的打印使用的是solidworks,其中有很多偏差就自行又添加了一些小组件,后期可能会发布一下完成版的外壳源码。

4.MQTT连接

1、先创建一下你的项目

2、设置两个主题来进行接受和发送,便于自行检查;

arduino部分的全部代码附上:

代码汇中的注释部分已经过分详细了,请自行查看即可;

#include #include //发布订阅库,也可以使用mqtt.h #include //连接mqtt const char* ssid = " "; //WIFI的ID const char* password = " "; //WIFI的PASSWORD const char* mqtt_server = " "; // mqtt服务器的地址。 const char* TOPIC = "set"; // 订阅信息主题 const char* Mqtt_pub_topic = "get"; // 订阅信息主题 const char* client_id = "esp32";//设备的客户端编号 char* sh = new char[10]; //定义两个字符串数组,用来存放温湿度的浮点数转换过来的字符串。 char* st = new char[10]; long lastMsg = 0; // 记录上一次发送信息的时间。 int freq = 50; // 1/50秒,50Hz的频率,20ms的周期,这个变量用来存储时钟基准。 int channel = 8; // 通道(高速通道(0 ~ 7)由80MHz时钟驱动,低速通道(8 ~ 15)由 1MHz 时钟驱动。) int resolution = 8; // 分辨率设置为8,就是2的8次方,用256的数值来映射角度,看下方的占空比函数。 const int led = 13; /*****将局部变量已改为全局变量(根据实际需求再自行调整)****/ int degree; float deadZone = 0; String push_msg = "OK"; //最好不要使用max、min...之类的词作为变量,容易被编译器识别成方法、类、函数... float maxs = 32;//对应2.5ms(2.5ms/(20ms/256)) /*****************************/ WiFiClient espClient; // 定义WLAN实例 PubSubClient client(espClient); // 定义PubSubClient的实例 /*****将int degree改为 int c,通过赋值修改degree的值******/ /*****由于该函数中return一个int类型数据,所以应将函数的返回值类型void改为int******/ int calculatePWM(int c) //定义函数用于输出PWM的占空比 { //0-180度 degree = c; /*****************************************************/ //20ms周期内,高电平持续时长0.5-2.5ms,对应0-180度舵机角度,参考上面的180度对应图。 deadZone = 6.4;//对应0.5ms(0.5ms/(20ms/256)) if (degree < 0) degree = 0; if (degree > 200) degree = 180; return (int)(((maxs - deadZone) / 180) * degree + deadZone); //返回度数对应的高电平的数值 } void setup() { Serial.begin(9600); ledcSetup(channel, freq, resolution); // 用于设置 LEDC 通道的频率和分辨率。 ledcAttachPin(led, channel); // 将通道与对应的引脚连接 // WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } client.setServer(mqtt_server, 1883);//设定MQTT服务器与使用的端口 client.setCallback(leddev); //设定回调程序,当ESP32收到订阅消息时会调用此方法 delay(5000); client.publish(Mqtt_pub_topic,push_msg.c_str()); Serial.println(push_msg); } /*****由于该函数中return一个int类型数据,所以应将函数的返回值类型void改为int******/ int leddev(char* topic, byte* payload, unsigned int length) /*************************************************************************/ { String msg=""; for (int i = 0; i < length; i++) { msg+= (char)payload[i]; } Serial.println(msg); if (msg == "1") { degree = 0; ledcWrite(channel, calculatePWM(180)); // 输出PWM,设置 LEDC 通道的占空比。 client.publish(Mqtt_pub_topic,push_msg.c_str()); return (int)(((maxs - deadZone) / 180) * degree + deadZone); //返回度数对应的高电平的数值 } else { Serial.printf("ok"); client.publish(Mqtt_pub_topic,push_msg.c_str()); ledcWrite(channel, calculatePWM(90)); // 输出PWM,设置 LEDC 通道的占空比。 } } void reconnect() { while (!client.connected()) { if (client.connect(client_id)) { client.subscribe(TOPIC); } else { delay(5000); } } } int flag = 0; void loop() { if (!client.connected()) //如果MQTT服务器连接不成功,则反复重试,连接成功后重新订阅。 { reconnect(); } client.loop(); if(flag==0){ client.publish(Mqtt_pub_topic,push_msg.c_str()); flag=1; Serial.println("发送ok!"); } // for (int d = 0; d


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3